package dk.mirasola.systemtraining.user.client.ui;

import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.DateCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.RowCountChangeEvent;
import com.google.gwt.view.client.SelectionChangeEvent;
import dk.mirasola.systemtraining.bridgewidgets.client.ui.RenderUtil;
import dk.mirasola.systemtraining.bridgewidgets.shared.model.Seat;
import dk.mirasola.systemtraining.user.client.dataprovider.BiddingSetDetailsDataProvider;
import dk.mirasola.systemtraining.user.client.i18n.BiddingSetDetailsTableTexts;
import dk.mirasola.systemtraining.user.client.ui.createbiddingsetwizard.CreateBiddingSetWizard;
import dk.mirasola.systemtraining.user.client.ui.table.STCellTableResource;
import dk.mirasola.systemtraining.user.client.ui.table.SafeHtmlColumn;
import dk.mirasola.systemtraining.user.shared.transfer.BiddingSetDetailsTO;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;


public class BiddingSetDetailsTable extends Composite {
    interface BiddingSetDetailsTableUiBinder extends UiBinder<Widget,BiddingSetDetailsTable>{}
    private static BiddingSetDetailsTableUiBinder uiBinder = GWT.create(BiddingSetDetailsTableUiBinder.class);
    private static BiddingSetDetailsTableTexts texts = GWT.create(BiddingSetDetailsTableTexts.class);

    @UiField(provided = true)
    CellTable<BiddingSetDetailsTO> table;
    @UiField
    Button create;
    @UiField
    Button delete;
    @UiField
    SimplePager pager;

    private MultiSelectionModel<BiddingSetDetailsTO> selectionModel = new MultiSelectionModel<BiddingSetDetailsTO>();
    private BiddingSetDetailsDataProvider dataProvider = new BiddingSetDetailsDataProvider();

    public BiddingSetDetailsTable() {
        initTable();
        initWidget(uiBinder.createAndBindUi(this));
        dataProvider.addDataDisplay(table);
        pager.setDisplay(table);

        initCreateButton();
        initDeleteButton();
        initSelectionModel();
    }

    private void initSelectionModel() {
        selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
            @Override
            public void onSelectionChange(SelectionChangeEvent event) {
                Set<BiddingSetDetailsTO> sels = selectionModel.getSelectedSet();
                delete.setEnabled(sels.size() > 0);
            }
        });
    }

    private void initDeleteButton() {
        delete.setEnabled(false);
        delete.setHTML(texts.deleteButton());
        delete.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                Set<BiddingSetDetailsTO> sels = selectionModel.getSelectedSet();
                selectionModel.clear();
                if (sels != null && sels.size() > 0) {
                    Set<String> ids = new HashSet<String>();
                    for (BiddingSetDetailsTO sel : sels) {
                        ids.add(sel.getId());
                    }
                    dataProvider.deleteBiddingSets(ids);
                }
            }
        });
    }

    private void initCreateButton() {
        create.setHTML(texts.newButton());
        create.setEnabled(false);
        pager.getDisplay().addRowCountChangeHandler(new RowCountChangeEvent.Handler() {
            @Override
            public void onRowCountChange(RowCountChangeEvent event) {
                create.setEnabled(event.getNewRowCount() < dataProvider.getMaxBiddingSets());
            }
        });
        create.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                final PopupPanel popupPanel = new PopupPanel(false, true);
                popupPanel.setAnimationEnabled(true);
                popupPanel.setSize("310px", "450px");
                final CreateBiddingSetWizard wizard = new CreateBiddingSetWizard();
                wizard.getCancel().addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        popupPanel.hide();
                    }
                });
                wizard.getFinish().addClickHandler(new ClickHandler() {
                    @Override
                    public void onClick(ClickEvent event) {
                        popupPanel.hide();
                        dataProvider.createBiddingSet(table,wizard.getCreateBiddingSetTO());
                    }
                });
                popupPanel.setWidget(wizard);
                popupPanel.center();
            }
        });
    }

    private void initTable() {
        CellTable.Resources resources = GWT.create(STCellTableResource.class);

        table = new CellTable<BiddingSetDetailsTO>(10, resources);
        table.setSelectionModel(selectionModel);

        Column<BiddingSetDetailsTO, Boolean> selectColumn = new Column<BiddingSetDetailsTO, Boolean>(new CheckboxCell(true, true)) {
            @Override
            public Boolean getValue(BiddingSetDetailsTO object) {
                return selectionModel.isSelected(object);
            }
        };
        selectColumn.setFieldUpdater(new FieldUpdater<BiddingSetDetailsTO, Boolean>() {
            @Override
            public void update(int index, BiddingSetDetailsTO object, Boolean value) {
                selectionModel.setSelected(object, value);
            }
        });

        TextColumn<BiddingSetDetailsTO> nameColumn = new TextColumn<BiddingSetDetailsTO>() {
            @Override
            public String getValue(BiddingSetDetailsTO details) {
                return details.getName();
            }
        };

        TextColumn<BiddingSetDetailsTO> descColumn = new TextColumn<BiddingSetDetailsTO>() {
            @Override
            public String getValue(BiddingSetDetailsTO details) {
                return details.getDescription();
            }
        };

        TextColumn<BiddingSetDetailsTO> boardsColumn = new TextColumn<BiddingSetDetailsTO>() {
            @Override
            public String getValue(BiddingSetDetailsTO detail) {
                return String.valueOf(detail.getBoardsCount());
            }
        };

        TextColumn<BiddingSetDetailsTO> northEmailColumn = new TextColumn<BiddingSetDetailsTO>() {
            @Override
            public String getValue(BiddingSetDetailsTO detail) {
                return detail.getNorthEmail();
            }
        };

        TextColumn<BiddingSetDetailsTO> southEmailColumn = new TextColumn<BiddingSetDetailsTO>() {
            @Override
            public String getValue(BiddingSetDetailsTO detail) {
                return detail.getSouthEmail();
            }
        };

        SafeHtmlColumn<BiddingSetDetailsTO> stateColumn = new SafeHtmlColumn<BiddingSetDetailsTO>() {
            @Override
            public void render(Cell.Context context, BiddingSetDetailsTO object, SafeHtmlBuilder sb) {
                super.render(context, object, sb);
            }

            @Override
            public SafeHtml getValue(BiddingSetDetailsTO detail) {
                if (detail.isCompleted()) {
                    return texts.finishState();
                } else {
                    Seat seat = detail.getInTurn();
                    if (seat == null) {
                        return SafeHtmlUtils.fromTrustedString("");
                    } else {
                        return texts.progressState(RenderUtil.renderSeatLowercase(seat));
                    }
                }
            }
        };

        Column<BiddingSetDetailsTO,Date> createdColumn = new Column<BiddingSetDetailsTO,Date>(new DateCell()) {
            @Override
            public Date getValue(BiddingSetDetailsTO biddingSetDetailsTO) {
                return biddingSetDetailsTO.getCreated();
            }
        };


        table.addColumn(selectColumn);
        table.addColumn(nameColumn, texts.nameColumn());
        table.addColumn(descColumn, texts.descriptionColumn());
        table.addColumn(boardsColumn, texts.boardsColumn());
        table.addColumn(northEmailColumn, texts.northEmailColumn());
        table.addColumn(southEmailColumn, texts.southEmailColumn());
        table.addColumn(stateColumn, texts.stateColumn());
        table.addColumn(createdColumn, texts.createColumn());

    }
}
